// Copyright@ChenChao


#include "Character/CCharacter.h"

#include "Components/WidgetComponent.h"
#include "GAS/CAbilitySystemComponent.h"
#include "GAS/CAttributeSet.h"
#include "Kismet/GameplayStatics.h"
#include "UI/Widget/OverHeadStateGauge.h"

// Sets default values
ACCharacter::ACCharacter()
{
 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = false;

	// 网格体无碰撞
	GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);

	//添加组件
	CAbilitySystemComponent = CreateDefaultSubobject<UCAbilitySystemComponent>(TEXT("CAbilitySystemComponent"));
	CAttributeSet = CreateDefaultSubobject<UCAttributeSet>(TEXT("CAttributeSet"));

	OverHeadWidgetComponent = CreateDefaultSubobject<UWidgetComponent>(TEXT("OverHeadWidgetComponent"));
	OverHeadWidgetComponent->SetupAttachment(GetRootComponent());
}

void ACCharacter::PossessedBy(AController* NewController)
{
	Super::PossessedBy(NewController);
	ServerSideInit();

}

void ACCharacter::ServerSideInit()
{
	CAbilitySystemComponent->InitAbilityActorInfo(this, this);	//应用能力系统组件前都要初始化
	CAbilitySystemComponent->ApplyInitialEffects();		//效果初始化
	CAbilitySystemComponent->GiveInitialAbilities();	//能力初始化
}

void ACCharacter::ClientSideInit()
{
	CAbilitySystemComponent->InitAbilityActorInfo(this, this);	//应用能力系统组件前都要初始化
}

UAbilitySystemComponent* ACCharacter::GetAbilitySystemComponent() const
{
	return CAbilitySystemComponent;
}

void ACCharacter::ConfigureOverHeadStateWidget()
{
	if (!OverHeadWidgetComponent)
	{
		UE_LOG(LogTemp, Error, TEXT("OverHeadWidgetComponent is NULL"));
		return;
	}
	//如果是本地玩家控制的角色，不显示状态条
	if (IsLocallyControlledByPlayer())
	{
		OverHeadWidgetComponent->SetHiddenInGame(true);
		return;
	}
	//得到小部件：头顶属性条
	UOverHeadStateGauge* OverHeadStateGauge = Cast<UOverHeadStateGauge>(OverHeadWidgetComponent->GetUserWidgetObject());
	if (OverHeadStateGauge)
	{
		//调用能力系统组件，并配置它
		OverHeadStateGauge ->ConfigWithASC(GetAbilitySystemComponent());
		OverHeadWidgetComponent->SetHiddenInGame(false);

		GetWorldTimerManager().ClearTimer(VisibilityCheckTimerHandle);
		GetWorldTimerManager().SetTimer(VisibilityCheckTimerHandle, this, &ACCharacter::UpdateHeadGaugeVisibility, CheakUpdateRate, true);
	}
}

bool ACCharacter::IsLocallyControlledByPlayer() const
{
	return GetController() && GetController()->IsLocalPlayerController();
}

void ACCharacter::UpdateHeadGaugeVisibility()
{
	//测算距离
	APawn* PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
	if (!PlayerPawn) return;
	float Distance = FVector::DistSquared(GetActorLocation(), PlayerPawn->GetActorLocation());
	//隐藏状态条
	OverHeadWidgetComponent->SetHiddenInGame(Distance > CheakUpdateDistance*CheakUpdateDistance);
}

void ACCharacter::BeginPlay()
{
	Super::BeginPlay();
	ConfigureOverHeadStateWidget();
}
